package com.myfum.mobile.tetris.views
{
	import com.myfum.mobile.tetris.Config;
	import com.myfum.mobile.tetris.data.TetrisMap;
	import com.myfum.mobile.tetris.data.cubes.CubeData;
	import com.myfum.mobile.tetris.data.cubes.DropingCubeData;
	import com.myfum.mobile.tetris.data.cubes.EmptyCubeData;
	import com.myfum.mobile.tetris.data.shapes.ShapeData;
	import com.myfum.mobile.tetris.events.MapEvent;
	import com.myfum.mobile.tetris.interfaces.IShape;
	import com.myfum.mobile.tetris.interfaces.ISkinItem;
	
	import flare.basic.Scene3D;
	import flare.basic.Viewer3D;
	import flare.core.Light3D;
	import flare.core.Pivot3D;
	import flare.materials.Shader3D;
	import flare.materials.filters.AlphaMaskFilter;
	import flare.materials.filters.ColorFilter;
	import flare.primitives.Cube;
	import flare.primitives.Plane;
	
	import flash.display.BitmapData;
	import flash.display.StageAlign;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.utils.Dictionary;
	
	import org.robotlegs.mvcs.Mediator;
	
	public class TetrisStageMediator extends Mediator
	{
		[Inject]
		public var view:TetrisStage;
		[Inject]
		public var map:TetrisMap;
		
		private var scene:Scene3D;
		private var tetris:Vector.<Tetris>;
		private var container:Pivot3D;
		
		public function TetrisStageMediator()
		{
			super();
		}
		
		private function init():void{
			drawGrid();
			
			init3d();
		}
		
		private function init3d():void{
			scene = new Scene3D(view);
			scene.camera.setPosition(0, 0, -30);
			tetris = new Vector.<Tetris>();
			
			scene.setScale(.3, .3, .3);
			//var axis:Pivot3D = scene.addChildFromFile("resources/axis.f3d");
			
			container = new Pivot3D();
			
			scene.addChild(container);
			
			var p2:Plane = new Plane("up", Config.CUBE_SIZE_3D*Config.STAGE_WIDTH, Config.CUBE_SIZE_3D*Config.STAGE_HEIGHT, 1);
			//container.addChild(p2);
			p2.x = Config.CUBE_SIZE_3D*Config.STAGE_WIDTH/2;
			p2.y = Config.CUBE_SIZE_3D*Config.STAGE_HEIGHT/2;
			
			var light:Light3D = new Light3D();
			light.setPosition( 0, 300, -400 );
			scene.addChild(light);
			
			container.x = -Config.CUBE_SIZE_3D*Config.STAGE_WIDTH/2;
			container.y = -Config.CUBE_SIZE_3D*Config.STAGE_HEIGHT/2;
			
			scene.camera.lookAt(scene.x, scene.y, scene.z);
			scene.mouseEnabled = false;
		}
		
		private function onRender(e:Event):void{
			
		}
		
		override public function onRegister():void{
//			eventMap.mapListener(eventDispatcher, MapEvent.MAP_CHANGE, onMapChange);
			eventMap.mapListener(eventDispatcher, MapEvent.MAP_APPEND, onMapAppend);
			init();
		}
		
		private function onRedrawMap(e:MapEvent):void{
			//redrawMap();
			redrawMap3d();
		}
		
		private function onMapAppend(e:MapEvent):void{
			var t:Tetris = new Tetris(e.now as ShapeData);
			mediatorMap.createMediator(t);
			tetris.push(t);
			container.addChild(t);
		}
		
		private function onMapChange(e:MapEvent):void{
			/*eraseCubes(e.was.cubes);
			updateCubes(e.now.cubes);*/
		}
		
		private function drawGrid():void{
			/*view.graphics.beginFill(0xffcc00, .3);
			view.graphics.drawRect(0, 0, Config.CUBE_SIZE*Config.STAGE_WIDTH, Config.CUBE_SIZE*Config.STAGE_HEIGHT);
			view.graphics.endFill();
			
			view.graphics.lineStyle(1, 0, .7);
			for(var i:int = 0;i<Config.STAGE_WIDTH+1;i++){
				view.graphics.moveTo(i*Config.CUBE_SIZE, 0);
				view.graphics.lineTo(i*Config.CUBE_SIZE, Config.CUBE_SIZE*Config.STAGE_HEIGHT);
			}
			for(i = 0;i<Config.STAGE_HEIGHT+1;i++){
				view.graphics.moveTo(0, Config.CUBE_SIZE*i);
				view.graphics.lineTo(Config.STAGE_WIDTH*Config.CUBE_SIZE, Config.CUBE_SIZE*i);
			}*/
		}
		
		private function redrawMap3d():void{
			var p:Point = new Point();
			var c:CubeData;
			var cube:Cube;
			for(var i:int = Config.STAGE_HEIGHT - 1;i >= 0;i--){
				for(var j:int = 0;j<Config.STAGE_WIDTH;j++){
					p.x = j;
					p.y = i;
					c = map.getCubeDataByPoint(p);
					if(c is EmptyCubeData){
						continue;
					}
					if(c){
						cube = new Cube("", 4, 4, 4);
						cube.x = 4*c.x;
						cube.y = -4*c.y;
						scene.addChild(cube);
					}
				}
			}
		}
		
		/*private function redrawMap():void{
			var bd:BitmapData = view.getBitmap().bitmapData;
			bd.lock();
			var empty:BitmapData = new BitmapData(bd.width, bd.height, true, 0);
			bd.copyPixels(empty, bd.rect, new Point());
			var p:Point = new Point();
			var c:CubeData;
			for(var i:int = Config.STAGE_HEIGHT - 1;i >= 0;i--){
				for(var j:int = 0;j<Config.STAGE_WIDTH;j++){
					p.x = j;
					p.y = i;
					c = map.getCubeDataByPoint(p);
					if(c is EmptyCubeData){
						continue;
					}
					if(c){
						bd.copyPixels(c.skin, c.skin.rect, new Point(Config.CUBE_SIZE*c.x, Config.CUBE_SIZE*(c.y)));
					}
				}
			}
			bd.unlock();
		}
		
		private function updateCubes(cubes:Vector.<DropingCubeData>):void{
			if(cubes == null){
				return;
			}
			var p:Point = new Point();
			var bd:BitmapData = view.getBitmap().bitmapData;
			bd.lock();
			for each(var cube:CubeData in cubes){
				p.x = cube.point.x * Config.CUBE_SIZE;
				p.y = cube.point.y * Config.CUBE_SIZE;
				bd.copyPixels(cube.skin, cube.skin.rect, p);
			}
			bd.unlock();
		}
		
		private function eraseCubes(cubes:Vector.<DropingCubeData>):void{
			if(cubes == null){
				return;
			}
			var empty:BitmapData = new BitmapData(Config.CUBE_SIZE, Config.CUBE_SIZE, true, 0);
			var p:Point = new Point();
			var bd:BitmapData = view.getBitmap().bitmapData;
			bd.lock();
			for each(var cube:CubeData in cubes){
				p.x = cube.point.x * Config.CUBE_SIZE;
				p.y = cube.point.y * Config.CUBE_SIZE;
				bd.copyPixels(empty, empty.rect, p);
			}
			bd.unlock();
		}*/
	}
}